// — — — — — — — — — — — — glwidget.cpp — — — — — — — —
#include "GLWidget.h"
GLWidget::GLWidget(QWidget *parent) : QGLWidget(parent)
{
}




QImage loadTexture2(char *filename, GLuint &textureID){
    glEnable(GL_TEXTURE_2D); // Enable texturing

    glGenTextures(1, &textureID); // Obtain an id for the texture
    glBindTexture(GL_TEXTURE_2D, textureID); // Set as the current texture

    glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
    glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_DECAL);

    QImage im(filename);
    QImage tex = QGLWidget::convertToGLFormat(im);

    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, tex.width(), tex.height(), 0, GL_RGBA, GL_UNSIGNED_BYTE, tex.bits());

    glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR);
    glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR);

    glDisable(GL_TEXTURE_2D);

    return tex;
}



GLuint backgroundimage;
void  GLWidget::init(){
   tex =  loadTexture2((char*)"d://temp//people.png", backgroundimage);
   init_corner_anchors(corners,anchors , tex );
}


void GLWidget::initializeGL()
{
    init();
  glClearColor(0, 0, 1, 1); //define blue color as background color
}


void GLWidget::resizeGL(int w, int h)
{
}


float bezierPoint(float x0, float x1, float x2, float x3, float t) {
    float   ax, bx, cx;
    float   ay, by, cy;
    float   t2, t3;
    float   x;

    // polynomial coefficients
    cx = 3.0f * (x1 - x0);
    bx = 3.0f * (x2 - x1) - cx;
    ax = x3 - x0 - cx - bx;

    t2 = t * t;
    t3 = t2 * t;
    x = (ax * t3) + (bx * t2) + (cx * t) + x0;

    return x;
}


float ofRandom(float x, float y) {
    float high = std::max(x, y);
    float low = std::min(x, y);
    return std::max(low, (low + ((high - low) * rand() / float(RAND_MAX))) * (1.0f - std::numeric_limits<float>::epsilon()));
}

void  GLWidget::init_corner_anchors(QVector<QPoint> &corners , QVector<QPoint>& anchors, QImage &img){


    int width = img.width();
    int height = img.height();

    int startx = 0;
    int starty = 0;
    corners.push_back(QPoint( 0,   +  0));
    corners.push_back(QPoint( startx + width, starty +  0));
    //corners.push_back(QPoint( 0, 0));
    corners.push_back(QPoint(startx + width,  starty +  height));
    corners.push_back(QPoint( startx + 0,  starty +  height));

    //anchors.push_back(QPoint(-   width, -height * 0.33333));
    //anchors.push_back(QPoint(startx + 0,  starty +qRound(height * 0.33333  ) ));
    anchors.push_back(QPoint(width / 2 ,  height / 2));
    anchors.push_back(QPoint(startx + qRound(width * 0.33333 ), starty + 0));
    anchors.push_back(QPoint(startx + qRound(width * 0.66666), starty + 0));
    anchors.push_back(QPoint(startx + width,  starty + qRound(height * 0.3333)));
    anchors.push_back(QPoint(startx + width, starty + qRound(height * 0.66666)));
    anchors.push_back(QPoint(startx + qRound(width * 0.66666), starty + height));
    anchors.push_back(QPoint(startx + qRound(width * 0.33333 ), starty + height));
    anchors.push_back(QPoint(startx + 0, starty + qRound(height * 0.66666)));


//    corners.resize(4);
//    float rnd_x = ofRandom(0.1, 0.6);
//    float rnd_y = ofRandom(0.1, 0.6);
//    corners[0] = QPoint(width * (0.0 + rnd_x), height * (0.0 + rnd_y));
//    corners[1] = QPoint(width * (0.3 + rnd_x), height * (0.0 + rnd_y));
//    corners[2] = QPoint(width * (0.3 + rnd_x), height * (0.3 + rnd_y));
//    corners[3] = QPoint(width * (0.0 + rnd_x), height * (0.3 + rnd_y));

//    // top left first then clockwise
//    anchors.resize(8);
//    anchors[0] = QPoint(width * (0.0 + rnd_x), height * (0.1 + rnd_y));
//    anchors[1] = QPoint(width * (0.1 + rnd_x), height * (0.0 + rnd_y));
//    anchors[2] = QPoint(width * (0.2 + rnd_x), height * (0.0 + rnd_y));
//    anchors[3] = QPoint(width * (0.3 + rnd_x), height * (0.1 + rnd_y));
//    anchors[4] = QPoint(width * (0.3 + rnd_x), height * (0.2 + rnd_y));
//    anchors[5] = QPoint(width * (0.2 + rnd_x), height * (0.3 + rnd_y));
//    anchors[6] = QPoint(width * (0.1 + rnd_x), height * (0.3 + rnd_y));
//    anchors[7] = QPoint(width * (0.0 + rnd_x), height * (0.2 + rnd_y));
}



#include <QDebug>
void GLWidget::paintGL()
{

setGeometry(0, 0, 1920, 1080);
glViewport(-0, -0, 1920 , 1080 );
    int gridRes = 20;
    QVector<QVector<QPoint>> bezSurfPoints(gridRes + 1 ,QVector<QPoint>(gridRes + 1,QPoint(0,0)));



    for(int i = 0; i <= gridRes; i++) {
        for(int j = 0; j <= gridRes; j++) {
            float start_x = bezierPoint(corners[0].x(), anchors[0].x(), anchors[7].x(), corners[3].x(), (float)j/gridRes);
            float end_x = bezierPoint(corners[1].x(), anchors[3].x(), anchors[4].x(), corners[2].x(),   (float)j/gridRes);
            float start_y = bezierPoint(corners[0].y(), anchors[0].y(), anchors[7].y(), corners[3].y(), (float)j/gridRes);
            float end_y = bezierPoint(corners[1].y(), anchors[3].y(), anchors[4].y(), corners[2].y(),   (float)j/gridRes);

            float x = bezierPoint(start_x, ((anchors[1].x() - anchors[6].x()) * (1.0f - (float)j/gridRes)) + anchors[6].x(), ((anchors[2].x() - anchors[5].x()) * (1.0f - (float)j/gridRes)) + anchors[5].x(), end_x, (float)i/gridRes);
            float y = bezierPoint(start_y, ((anchors[1].y() - anchors[6].y()) * (1.0f - (float)j/gridRes)) + anchors[6].y(), ((anchors[2].y() - anchors[5].y()) * (1.0f - (float)j/gridRes)) + anchors[5].y(), end_y, (float)i/gridRes);

        // 左移 width/2 下移 height /2
            x = x * 2  - 1920 ;
            y = y * 2 -  1080 ;
        bezSurfPoints[i][j] = QPoint(x, y);
        //bezSurfPoints[i][j] = QPoint(i, j);
        }
    }




    int width = 1920;
    int height = 1080;



//    for(int i = 0; i < gridRes; i++) {
//        for(int j = 0; j < gridRes; j++) {
//            glEnable(GL_TEXTURE_2D);
//             glBindTexture(GL_TEXTURE_2D, 1);
//            glBegin(GL_QUADS);
//            qDebug()<< bezSurfPoints[i][j].x() << "," << bezSurfPoints[i][j].y();

//                 glTexCoord2f((i) * (tex.width()/gridRes / float(width)), (j) * (tex.height()/gridRes) / float(height));
//                glVertex2f(bezSurfPoints[i][j].x()  / float(width)   , bezSurfPoints[i][j].y() / float(height));

//                glTexCoord2f((i+1) * (tex.width()/gridRes / float(width)), (j) * (tex.height()/gridRes) / float(height));
//                glVertex2f( bezSurfPoints[i+1][j].x()  / float(width), bezSurfPoints[i+1][j].y() / float(height));

//                glTexCoord2f((i+1) * (tex.width()/gridRes) / float(width), (j+1) * (tex.height()/gridRes) / float(height));
//                glVertex2f(bezSurfPoints[i+1][j+1].x()  / float(width), bezSurfPoints[i+1][j+1].y() / float(height));

//                glTexCoord2f((i) * (tex.width()/gridRes) / float(width), (j+1) * (tex.height()/gridRes) / float(height));
//                glVertex2f(bezSurfPoints[i][j+1].x()  / float(width), bezSurfPoints[i][j+1].y() / float(height));

//            glEnd();
//          //  glDisable(GL_TEXTURE_2D);
//        }
//    }





        int scale = 1;
        for(int i = 0; i < gridRes; i++) {
            for(int j = 0; j < gridRes; j++) {
                glEnable(GL_TEXTURE_2D);
                 glBindTexture(GL_TEXTURE_2D, 1);
                glBegin(GL_QUADS);
                qDebug()<< bezSurfPoints[i][j].x() << "," << bezSurfPoints[i][j].y();

                     glTexCoord2f((i) * (tex.width()/gridRes / float(width)), (j) * (tex.height()/gridRes) / float(height));
                    glVertex2f( scale* bezSurfPoints[i][j].x()  / float(width)   ,  scale* bezSurfPoints[i][j].y() / float(height));

                    glTexCoord2f((i+1) * (tex.width()/gridRes / float(width)), (j) * (tex.height()/gridRes) / float(height));
                    glVertex2f( scale * bezSurfPoints[i+1][j].x()  / float(width),  scale * bezSurfPoints[i+1][j].y() / float(height));

                    glTexCoord2f((i+1) * (tex.width()/gridRes) / float(width), (j+1) * (tex.height()/gridRes) / float(height));
                    glVertex2f( scale *bezSurfPoints[i+1][j+1].x()  / float(width),  scale *bezSurfPoints[i+1][j+1].y() / float(height));

                    glTexCoord2f((i) * (tex.width()/gridRes) / float(width), (j+1) * (tex.height()/gridRes) / float(height));
                    glVertex2f( scale * bezSurfPoints[i][j+1].x()  / float(width),  scale * bezSurfPoints[i][j+1].y() / float(height));

                glEnd();
              //  glDisable(GL_TEXTURE_2D);
            }
        }



//    glClear(GL_COLOR_BUFFER_BIT);
//    glColor3f(1,0,0);
//    glBegin(GL_LINES);
//    glVertex2f(0 ,0);
//    glVertex2f(-0.99, 0.99);
//   // glVertex2f(-0.3 , -0.3);


    glEnd();






    int d = 1;

}

void GLWidget::mousePressEvent(QMouseEvent *event)
{


            GLubyte* pPixelData;
            pPixelData = (GLubyte*)malloc(1920 * 1080 * 4 * sizeof(GLubyte));//分配内存
            if (pPixelData == 0)
                return ;
            glReadBuffer(GL_FRONT);//保存窗口渲染的结果
            glPixelStorei(GL_UNPACK_ALIGNMENT, 4);//解压窗口数据结构
            glReadPixels(0, 0, 1920, 1080, GL_RGBA, GL_UNSIGNED_BYTE, pPixelData);//存储像素数据

            QImage img((uchar*)pPixelData, 1920, 1080, QImage::Format_ARGB32);
            QImage rlt(img.size(), QImage::Format_ARGB32);
            for(int y =0; y < img.height();y++){
                uchar * offset = img.scanLine(y);
                uchar * dst = rlt.scanLine(rlt.height() - y - 1);
                for (int x = 0; x < img.width(); ++x, offset = offset +4, dst = dst + 4) {
                    dst[2]  = offset[0];
                    dst[1] = offset[1];
                    dst[0] = offset[2];
                    dst[3] = offset[3];
                }


            }
            rlt.save("d://temp//rltxxx.png");



}
